package com.snap.vseries.ui;

import android.app.Dialog;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.orhanobut.logger.Logger;
import com.snap.vseries.AppConfig;
import com.snap.vseries.Constants;
import com.snap.vseries.MoleApplication;
import com.snap.vseries.R;
import com.snap.vseries.analyze.AnalyzeManager;
import com.snap.vseries.analyze.OnAnalyzeListener;
import com.snap.vseries.base.BaseActivity;
import com.snap.vseries.bean.AnalysisProtocol;
import com.snap.vseries.bean.ExpInfo;
import com.snap.vseries.dialog.AnalysisDialog;
import com.snap.vseries.fragment.ChartAmpFitFragment;
import com.snap.vseries.fragment.DetailAnalyzeFragment;
import com.snap.vseries.fragment.DetailInfoFragment;
import com.snap.vseries.fragment.DetailLogFragment;
import com.snap.vseries.framework.MoleExecutor;
import com.snap.vseries.framework.MoleTask;
import com.snap.vseries.listener.IFragmentListener;
import com.snap.vseries.logger.LoggerUtil;
import com.snap.vseries.manager.FileManager;
import com.snap.vseries.model.DBManager;
import com.snap.vseries.pdf.PdfManager;
import com.snap.vseries.ui.widget.ExportDialogView;
import com.snap.vseries.ui.widget.ExportProcessView;
import com.snap.vseries.ui.widget.TextButton;
import com.snap.vseries.utils.ApkUtils;
import com.snap.vseries.utils.FileUtils;
import com.snap.vseries.utils.OkHttpUtil;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import butterknife.BindView;
import butterknife.OnClick;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.RequestBody;

import static com.snap.vseries.ui.GeneralActivity.NO_USB;
import static com.snap.vseries.ui.widget.ExportProcessView.ERROR;
import static com.snap.vseries.ui.widget.ExportProcessView.FINISH;
import static com.snap.vseries.ui.widget.ExportProcessView.RUNNING;

/**
 * 程序实验结果：分析、报告
 */
public class ExpResultActivity extends BaseActivity implements RadioGroup.OnCheckedChangeListener {
    @BindView(R.id.radio_group)
    RadioGroup radioGroup;


    private int currentCheckedId = -1;
    private DetailAnalyzeFragment analyzeFragment;
    private DetailInfoFragment infoFragment;
    private ExpInfo experimentInfo;
    private Dialog dialog;
    private String fileName;

    private Future future;
    private ExportProcessView runningProcess;
    private ExportDialogView exportDialogView;
    private FragmentTransaction ft;

    @Override
    protected int layoutResId() {
        return R.layout.activity_exp_result;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            currentCheckedId = savedInstanceState.getInt("currentCheckId");
        }
        fileName = getIntent().getStringExtra("fileName");
        if (TextUtils.isEmpty(fileName)) {
            Logger.e("查看实验详情失败！实验文件为空");
            return;
        }
        getDataFromFile(fileName);
        setExpRead();
    }


    private void getDataFromFile(String fileName) {
        showLoading("加载数据中...");
        future = MoleExecutor.getInstance().execute(new MoleTask<ExpInfo>() {
            @Override
            public ExpInfo runInBackground() {
                return FileManager.getInstance().getExpDataByName(fileName);
            }

            @Override
            public void onCompleted(ExpInfo result) {
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                if (result == null) {
                    showExceptionDialog("查看失败", "读取实验文件失败！");
                    return;
                }
                if (result.getProtocols() == null || result.getProtocols().size() == 0) {
                    List<AnalysisProtocol> protocols = new ArrayList<>();
                    protocols.add(new AnalysisProtocol());
                    protocols.add(new AnalysisProtocol());
                    protocols.add(new AnalysisProtocol());
                    protocols.add(new AnalysisProtocol());
                    result.setProtocols(protocols);
                    result.setAnalyzed(false);
                }

                experimentInfo = result;
                if (experimentInfo != null && experimentInfo.getProgramMeltStage() != null) {
//                    if (experimentInfo.getExperimentType() == Constants.EXPERIMENT_TYPE_MELT) {
//                        radio2.setVisibility(View.VISIBLE);
//                    } else {
//                        radio2.setVisibility(View.GONE);
//                    }
//                    if (experimentInfo.getTemplateInfo().getExperimentType() == Constants.EXPERIMENT_TYPE_QUANTITY) {
//                        radio5.setVisibility(View.VISIBLE);
//                    } else {
//                        radio5.setVisibility(View.GONE);
//                    }
                }
                if (!experimentInfo.isAnalyzed()) {
                    analyzeData();
                } else {
                    initViews();
                }
            }
        });
    }

    private void analyzeData() {
        showLoading("努力分析中...");
        OnAnalyzeListener onAnalyzeListener = percent -> {
            if (dialog != null && dialog.isShowing()) {
                TextView contentTv = dialog.findViewById(R.id.content_tv);
                contentTv.post(() -> contentTv.setText("努力分析中(" + percent + "%)..."));
            }
        };
        future = MoleExecutor.getInstance().execute(new MoleTask<Void>() {
            @Override
            public Void runInBackground() {
                AnalyzeManager.doAnalyze(experimentInfo);
                return null;
            }

            @Override
            public void onCompleted(Void result) {
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
//                postResult(experimentInfo);
                initViews();
            }
        });
    }
//      try {
//        AnalyzeManager.doAnalyze(expInfo);
//        postResult(expInfo);
//    } catch (Exception e) {
//        Logger.e("postResult失败：" + e.getMessage());
//    }
//    //输出结束语句
//        LoggerUtil.Log(deviceId, expInfo.getName(), "***************** exp end:" + (new Date().toLocaleString()) + "*********************");
//}

    public void postResult(ExpInfo experimentInfo) {
        String url = "http://apicms.edengene.com.cn/api/tt/post";
        //        JSONObject jsonObject = new JSONObject();
//        try {
//            jsonObject.put("deviceid",1111111);//填写你们设备内部的编码，为了保险起见，传输给我们的时候，加上你们的公司简称全拼，具体简称与因顿沟通确认；
//            jsonObject.put("name","顺");
//            jsonObject.put("studentId","123123");
//            jsonObject.put("sex","小萌新");
//            jsonObject.put("data","I have pan");
//
//        } catch (JSONException e) {
//            e.printStackTrace();
//        }
        if (experimentInfo == null || experimentInfo.getHoleInfo() == null || experimentInfo.getHoleInfo().getChannelData() == null) {
            return;
        }
        float fam = experimentInfo.getHoleInfo().getChannelData().get(0).getCtValue();
        float vic = experimentInfo.getHoleInfo().getChannelData().get(1).getCtValue();
        float rox = experimentInfo.getHoleInfo().getChannelData().get(2).getCtValue();
        float cy5 = experimentInfo.getHoleInfo().getChannelData().get(3).getCtValue();
        String CT;
        String AG;
        if (fam < 35 && (vic >= 35 || vic == 0)) {
            CT = "C/C";
        } else if ((fam >= 35 || fam == 0) && vic < 35) {
            CT = "T/T";
        } else if (fam < 38 && vic < 38) {
            CT = "T/T";
        } else {
            CT = "重新取样进行测试";
        }
        if (rox < 36 && (cy5 >= 36 || cy5 == 0)) {
            AG = "C/C";
        } else if ((rox >= 36 || rox == 0) && cy5 < 36) {
            AG = "T/T";
        } else if (rox < 38 && cy5 < 38) {
            AG = "T/T";
        } else {
            AG = "重新取样进行测试";
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss", Locale.CHINA);
        String jsonString = "{\"deviceid\": \"MOLE123456\", \"time\": \"" + format.format(new Date()) + "\", \"nameK1\": \"510101\", \"k1_ct\": \"" + CT + "\", \"k1_ag\": \"" + AG + "\"}";
        RequestBody body = FormBody.create(MediaType.parse("application/json;charset=utf-8"), jsonString);
//        LoggerUtil.Log(deviceId, experimentInfo.getName(), "%s 开始发送数据");
        OkHttpUtil.getHttpRequest(url, body);
    }
    private void showExceptionDialog(String title, String content) {
        Dialog exceptionDialog = new Dialog(this, R.style.DimDialogStyle);
        exceptionDialog.setContentView(R.layout.dialog_exp_exception);
        exceptionDialog.setCanceledOnTouchOutside(true);
        exceptionDialog.setCancelable(true);
        TextButton knowBtn = exceptionDialog.findViewById(R.id.know_btn);
        TextView contentTv = exceptionDialog.findViewById(R.id.content_tv);
        TextView titleTv = exceptionDialog.findViewById(R.id.title_tv);
        contentTv.setText(content);
        titleTv.setText(title);
        knowBtn.setOnClickListener(v -> exceptionDialog.dismiss());
        exceptionDialog.show();
    }

    private void initViews() {
        radioGroup.findViewById(R.id.radio3).setVisibility(AppConfig.Dynamic.developer_permission ? View.VISIBLE : View.GONE);
        radioGroup.check(R.id.radio1);
        showFragment(R.id.radio1);
        radioGroup.setOnCheckedChangeListener(this);
    }

    private void setExpRead() {
        DBManager.get().getExpByName(fileName, entity -> {
            if (entity != null) {
                if (!entity.isRead()) {
                    entity.setRead(true);
                    DBManager.get().saveExp(entity, null);
                }
            }
        });
    }

    private void export() {
        exportDialogView = new ExportDialogView(this);
        exportDialogView.setOnClickListener(new ExportDialogView.OnSureListener() {
            @Override
            public void onSureClick(boolean pdf, boolean xls) {
                exportDialogView.dismiss();
                runningProcess = new ExportProcessView(ExpResultActivity.this, RUNNING);
                runningProcess.show();
                MoleExecutor.getInstance().execute(new MoleTask<String>() {
                    @Override
                    public String runInBackground() {
                        return export(pdf, xls);
                    }


                    @Override
                    public void onCompleted(String result) {
                        if (runningProcess != null && runningProcess.isShowing()) {
                            runningProcess.dismiss();
                        }
                        if (result.equals(NO_USB)) {
                            new ExportProcessView(ExpResultActivity.this, ERROR).setContentTv("未检测到U盘").show();
                        } else if (result.equals("")) {
                            new ExportProcessView(ExpResultActivity.this, FINISH).show();
                        } else {
                            new ExportProcessView(ExpResultActivity.this, ERROR).setContentTv(result.substring(0, result.length() - 1)).show();
                        }
                    }
                });
            }
        }).show();

    }

    /**
     * 导出的荧光图谱为选中的图谱
     *
     * @param pdf
     * @param xls
     * @return
     */
    public String export(boolean pdf, boolean xls) {
        StringBuilder errorContent = new StringBuilder();
        List<String> pathList = ApkUtils.getUSBPaths(MoleApplication.get());
        if (pathList == null || pathList.size() == 0) {
            errorContent.append("No USB flash drive detected");
            return errorContent.toString();
        }
        String usbPath = pathList.get(0) + File.separator + experimentInfo.getName();
//        String usbPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator + experimentInfo.getExperimentName();

        FileUtils.mkDirectory(new File(usbPath));

        Bitmap ampOriginBitmap = null;
        Bitmap ampFitBitmap = null;
        try {
            if (pdf) {
                View ampOriginView = analyzeFragment.getAmpOriginView();

                if (ampOriginView != null) {
                    ampOriginView.destroyDrawingCache();
                    ampOriginView.setDrawingCacheEnabled(true);
                    ampOriginView.buildDrawingCache();
                    ampOriginBitmap = ampOriginView.getDrawingCache();
                }
                ampFitBitmap = syncCreateFitFragment();
            }

            boolean xlsResult = !xls || FileManager.getInstance().exportExcel(experimentInfo, usbPath + File.separator + experimentInfo.getName() + ".xls");
            String generateTime = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA).format(new Date());
            boolean pdfResult = !pdf || PdfManager.get().makePdf(ExpResultActivity.this, ampOriginBitmap, ampFitBitmap, usbPath, generateTime, experimentInfo, false);
            if (!pdfResult && !xlsResult) {
                return errorContent.toString();
            }
            if (!pdfResult) {
                errorContent.append("Report、");//实验报告
            }
            if (!xlsResult) {
                errorContent.append("Data、");//荧光数据

            }
        } catch (Exception e) {
            Logger.e("ExportError:" + MoleApplication.printExceptionInfo(e));
        }
        return errorContent.toString();
    }

    private Bitmap syncCreateFitFragment() throws InterruptedException {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        IFragmentListener listener = new IFragmentListener() {
            @Override
            public void onFragmentAttachedToWindow() {
                lock.lock();
                condition.signal();
                lock.unlock();
            }
        };
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ChartAmpFitFragment ampFitFragmentClone = (ChartAmpFitFragment) getSupportFragmentManager().findFragmentByTag(Constants.CLONE_ANALYZE_FIT);
        Bundle bundle = analyzeFragment.getChooseInfo();
        boolean[] bs = new boolean[4];
        int channelFlag = 0;
        if (bundle != null) {
            bs = bundle.getBooleanArray("check");
            channelFlag = bundle.getInt("channelFlag");
        }
        if (ampFitFragmentClone == null) {
            ampFitFragmentClone = new ChartAmpFitFragment(experimentInfo);
            ampFitFragmentClone.setListener(listener, channelFlag, bs, false);
            ft.add(R.id.container_clone, ampFitFragmentClone, Constants.CLONE_ANALYZE_FIT);
            ft.commitAllowingStateLoss();
        } else {
            ampFitFragmentClone.setListener(listener, channelFlag, bs, true);
        }
        lock.lock();
        try {
            condition.await(5000, TimeUnit.MILLISECONDS);
        } finally {
            lock.unlock();
        }
        View ampFitView = ampFitFragmentClone.getAmpFitView();
        Bitmap ampFitBitmap = null;
        if (ampFitView != null) {
            ampFitView.destroyDrawingCache();
            ampFitView.setDrawingCacheEnabled(true);
            ampFitView.buildDrawingCache();
            ampFitBitmap = ampFitView.getDrawingCache();
        }
        return ampFitBitmap;
    }

    private void showLoading(String content) {
        dialog = new Dialog(this, R.style.DimDialogStyle);
        dialog.setContentView(R.layout.dialog_loading);
        TextView contentTv = dialog.findViewById(R.id.content_tv);
        contentTv.setText(content);
        dialog.setCanceledOnTouchOutside(true);
        dialog.setCancelable(true);
        dialog.show();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt("currentCheckId", currentCheckedId);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        showFragment(checkedId);
    }

    private void showFragment(int checkedId) {
        if (currentCheckedId == checkedId) {
            return;
        }
        currentCheckedId = checkedId;

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        analyzeFragment = (DetailAnalyzeFragment) fm.findFragmentByTag(DetailAnalyzeFragment.class.getSimpleName());
        infoFragment = (DetailInfoFragment) fm.findFragmentByTag(DetailInfoFragment.class.getSimpleName());
        DetailLogFragment logFragment = (DetailLogFragment) fm.findFragmentByTag(DetailLogFragment.class.getSimpleName());
        hideAll(ft);

        switch (currentCheckedId) {
            case R.id.radio1:
                if (infoFragment != null) {
                    ft.hide(infoFragment);
                }
                if (logFragment != null) {
                    ft.hide(logFragment);
                }
                if (analyzeFragment == null) {
                    analyzeFragment = new DetailAnalyzeFragment(experimentInfo);
                    ft.add(R.id.container, analyzeFragment, DetailAnalyzeFragment.class.getSimpleName());
                } else {
                    ft.show(analyzeFragment);
                }
                break;
            case R.id.radio2:
                if (analyzeFragment != null) {
                    ft.hide(analyzeFragment);
                }
                if (logFragment != null) {
                    ft.hide(logFragment);
                }
                if (infoFragment == null) {
                    infoFragment = new DetailInfoFragment(experimentInfo);
                    ft.add(R.id.container, infoFragment, DetailInfoFragment.class.getSimpleName());
                } else {
                    ft.show(infoFragment);
                }
                break;
            case R.id.radio3:
                if (infoFragment != null) {
                    ft.hide(infoFragment);
                }
                if (analyzeFragment != null) {
                    ft.hide(analyzeFragment);
                }
                if (logFragment == null) {
                    logFragment = new DetailLogFragment(experimentInfo);
                    ft.add(R.id.container, logFragment, DetailLogFragment.class.getSimpleName());
                } else {
                    ft.show(logFragment);
                }
                break;
            default:
        }
        ft.commitAllowingStateLoss();
    }

    private void hideAll(FragmentTransaction ft) {
        if (analyzeFragment != null) {
            ft.hide(analyzeFragment);
        }
        if (infoFragment != null) {
            ft.hide(infoFragment);
        }
    }

    @OnClick({R.id.leftWrapper, R.id.rightWrapper, R.id.protocol_btn})
    public void click(View view) {
        switch (view.getId()) {
            case R.id.leftWrapper:
                finish();
                break;
            case R.id.rightWrapper:
                if (experimentInfo != null) {
                    export();
                }
                break;
            case R.id.protocol_btn:
                showAnalysisDialog();
                break;
            default:
        }
    }

    public void showAnalysisDialog() {
        new AnalysisDialog().setParam(experimentInfo, this::analysisChanged).show(getSupportFragmentManager(), "");
    }

    private void analysisChanged() {
        FragmentManager fm = getSupportFragmentManager();
        ft = fm.beginTransaction();
        List<Fragment> fragments = fm.getFragments();
        for (int i = 0; i < fragments.size(); i++) {
            ft.remove(fragments.get(i));
        }
        ft.commitAllowingStateLoss();
        currentCheckedId = 0;
        analyzeData();
    }

    @Override
    protected void onDestroy() {
        if (future != null) {
            future.cancel(true);
        }
        super.onDestroy();
    }
}
